package com.bardsoftware.foronuvolo.data;

import static com.bardsoftware.foronuvolo.data.CollectionsUtil.first;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


import com.bardsoftware.foronuvolo.client.Urls;
import com.bardsoftware.foronuvolo.server.ForoNuvoloConstants;
import com.bardsoftware.foronuvolo.server.MessageCache;
import com.bardsoftware.foronuvolo.server.WikiMessageFormatter;
import com.google.appengine.api.datastore.Key;
import com.google.gdata.util.common.base.CharEscapers;
import com.google.appengine.repackaged.com.google.common.base.Pair;
import com.google.appengine.repackaged.com.google.common.base.StringUtil;

public class DiscussionsViewItem implements Serializable {
    private static final Pattern TITLE = Pattern.compile("^(\\s*=)([^=]+)(=\\s*)$");
    private final String username;
    private final Date startDate;
    private final String viewLink;
    private final int replyCount;
    private final String text;
    private final Boolean truncated;
    private final String myRefID;
    private final String myTitle;
    private final List<String> tags;
    private final Long rating;
    private final Long longID;
    private final ArrayList<String> voters;

    public DiscussionsViewItem(Discussion d, MessageCache<Key, Pair<String, Boolean>> messageTextCache, WikiMessageFormatter formatter) {
        final Message message = first(d.getSortedMessages());
        this.replyCount = d.getReplyCount();
        this.startDate = message.getCreation();
        this.viewLink = ForoNuvoloConstants.ANSWERS_VIEW_PATH + d.getCreationOrder() + "#" + replyCount;
        this.username = message.getUserDisplayName();
        this.myRefID = d.getCreationOrder();
        this.tags = d.getTags();
        this.rating = d.getRating();
        this.voters = d.getUsersWhoVoted();
        this.longID = d.getID();

        Pair<String, Boolean> cachedText = messageTextCache.get(message.getID());
        if (cachedText != null) {
            this.text = cachedText.getFirst();
            this.truncated = cachedText.getSecond();
            int posTitle = this.text.indexOf("<a class=titlelink");
            if (posTitle >= 0) {
                int posTitleStart = this.text.indexOf("\">", posTitle);
                int posTitleEnd = this.text.indexOf("</a>", posTitleStart);
                myTitle = this.text.substring(posTitleStart + 2, posTitleEnd);
            } else {
                myTitle = "";
            }
        } else {
            String title = "";
            String rawText = message.isTrusted() ? message.getText() : CharEscapers.htmlEscaper().escape(message.getText());
            int posLinebreak = rawText.indexOf('\n');
            if (posLinebreak >= 0) {
                String firstLine = rawText.substring(0, posLinebreak);
                Matcher matcher = TITLE.matcher(firstLine);
                if (matcher.find()) {
                    title = matcher.group(2);
                    rawText = matcher.group(1) + "<a class=titlelink href=\"" + viewLink + "\">" + title + "</a>"
                        + matcher.group(3) + rawText.substring(posLinebreak);
                }
            }
            myTitle = title;

            WikiMessageFormatter.Result r = formatter.format(rawText);
            String tmpText = r.text;
            for (String stripped = StringUtil.stripSuffix(tmpText, "<br>");
                 stripped != null && stripped.length() < tmpText.length();
                 stripped = StringUtil.stripSuffix(tmpText, "<br>")) {
                 tmpText = stripped;
            }
            this.text = tmpText;

            this.truncated = r.isTruncated;
            messageTextCache.put(message.getID(), new Pair<String, Boolean>(this.text, r.isTruncated));
        }
    }

    public String getUsername() {
        return username;
    }
    public Date getStartDate() {
        return startDate;
    }
    public String getViewLink() {
        return viewLink;
    }
    public int getReplyCount() {
        return replyCount;
    }
    public String getText() {
        return text;
    }
    public boolean getTruncated() {
        return truncated;
    }

    public static String getRefIDFromViewPath(String path) {
        return Urls.getDiscussionRefIDFromViewPath(path);
    }

    public String getRefID() {
        return myRefID;
    }

    public String getTitle() {
        return myTitle;
    }
    
    public List<String> getTags(){
    	return tags;
    }
    
    public Long getRating() {
		return rating;
	}
    
    public ArrayList<String> getVoters() {
    	return voters;
    }
    
    public Long getLongID() {
    	return longID;
    }
}
